package repository

import (
	"cs/internal/setting"
	"cs/internal/utils"
	"fmt"
	"strconv"
	"strings"
	"sync"
	"time"
)

// 自定义表名
var TablePre = "cs"
var conf = setting.Config

type ISysIDRepo interface {
	SaveID(id int, t int64) bool
}

type SysIDRepo struct {
	// Log      logger.ILogger `inject:""`
	BaseRepo BaseRepo `inject:"inline"`
}

// 查询账号
// repo.SelectID(id)
func (repo *SysIDRepo) SelectID(id int) bool {
	tableName := repo.GetTableName(id)
	sql := fmt.Sprintf("SELECT * FROM %s WHERE id=?", tableName)
	var idArr User
	err := repo.BaseRepo.Source.DB().Raw(sql, id).Find(&idArr).Error
	// fmt.Println("查询结果", idArr)
	if err != nil {
		return false
		// repo.Log.Errorf("select error", err)
	}
	return true
}

// 获取表名-分表
func (repo *SysIDRepo) GetTableName(id int) string {
	tableName := "cs_"
	tableName += strconv.Itoa(id % 1000)
	TablePre = tableName
	return tableName
}

// 写入账号
var lock sync.Mutex

func (repo *SysIDRepo) SaveID(id int, t int64) bool {
	//自动建表
	// lock.Lock()
	// tableName := repo.GetTableName(id)
	tableName := "cs"
	// create := repo.CreatTable(tableName)
	// lock.Unlock()
	ress := false
	// fmt.Println("create", create)
	// if create == true {
	//查询数据库中是否存在 id
	// res := repo.SelectID(id)
	// tt := time.Now()
	// timeStr := fmt.Sprintf("%d%d%d%d", tt.Year(), tt.Month(), tt.Day(), tt.Hour())
	// if res == false {
	/*

	 */
	sql := fmt.Sprintf("INSERT INTO %s(id, t) VALUES (?, ?)", tableName)
	fmt.Println(sql)
	err := repo.BaseRepo.Source.DB().Exec(sql, id, t).Error
	if err != nil {
		// repo.Log.Errorf("写入数据失败", err)

		// fmt.Println(err)
		str := fmt.Sprintf("%v", err)
		r := strings.Contains(str, "1062")
		if r {
			fmt.Println("已存在", id)
			//延迟执行
			// defer utils.WriteStrings(conf.App.DataPath+"quchong-has-"+timeStr+".txt", strconv.Itoa(id)+"\r\n", 0)
		} else {
			fmt.Println("插入失败", id, tableName)
			// defer utils.WriteStrings(conf.App.DataPath+"quchong-error-"+timeStr+".txt", strconv.Itoa(id)+"\r\n", 0)
		}

	} else {
		fmt.Println("插入成功", id)
		//去重后写入文件
		// defer utils.WriteStrings(conf.App.DataPath+"quchong-"+timeStr+".txt", strconv.Itoa(id)+"\r\n", 0)
		ress = true
	}
	// } else {
	// fmt.Println("已存在", id)
	// defer utils.WriteStrings(conf.App.DataPath+"quchong-has-"+timeStr+".txt", strconv.Itoa(id)+"\r\n", 0)
	// }
	// }

	return ress
}

// 删除账号
func (repo *SysIDRepo) DelID(id int) bool {
	tableName := repo.GetTableName(id)
	ress := false
	tt := time.Now()
	timeStr := fmt.Sprintf("%d%d%d%d", tt.Year(), tt.Month(), tt.Day(), tt.Hour())
	sql := fmt.Sprintf("DELETE FROM %s WHERE id=?", tableName)
	// fmt.Println(sql)
	err := repo.BaseRepo.Source.DB().Exec(sql, id).Error
	if err != nil {
		// repo.Log.Errorf("写入数据失败", err)
		// fmt.Println("删除失败", id)
		defer utils.WriteStrings(conf.App.DataPath+"delete-error-"+timeStr+".txt", strconv.Itoa(id)+"\r\n", 0)
	} else {
		// fmt.Println("删除成功", id)
		//去重后写入文件
		defer utils.WriteStrings(conf.App.DataPath+"delete-"+timeStr+".txt", strconv.Itoa(id)+"\r\n", 0)
		ress = true
	}

	return ress
}

type User struct {
	//通过在字段后面的标签说明，定义golang字段和表字段的关系
	//例如 `gorm:"column:username"` 标签说明含义是: Mysql表的列名（字段名)为username
	//这里golang定义的Username变量和MYSQL表字段username一样，他们的名字可以不一样。
	Id int64 `gorm:"column:id;unique_index:id;not null;type:bigint(20) DEFAULT 0;"` //unique_index:id;
	//创建时间，时间戳
	CreateTime int64 `gorm:"column:t;unique_index:id;not null;type:int(11) DEFAULT 0;"` //unique_index:id;
}

// 自定义表名
func (u *User) TableName() string {
	// return "id_" + TablePre
	return TablePre
}

// 创建数据表

func (repo *SysIDRepo) CreatTable(tableName string) bool {
	lock.Lock()
	TablePre = tableName
	// has := repo.BaseRepo.Source.DB().HasTable(&User{})
	// fmt.Println("has", has)
	// if has == false {
	// err := repo.BaseRepo.Source.DB().Set("gorm:table_options", "ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic").AutoMigrate(&User{}).Error
	err := repo.BaseRepo.Source.DB().Set("gorm:table_options", "ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Fixed").AutoMigrate(&User{}).Error
	lock.Unlock()
	if err != nil {
		// repo.Log.Errorf("创建表失败", err)
		fmt.Println("建表失败", TablePre)
		return false
	}
	// }
	// repo.Log.Info("写入数据成功", err)
	return true
}
